Skip to content

Go1.23 Rangeover Func

go
package main

import (
	"fmt"
	"iter"
	"math/rand"
)

type void struct{}

type coro struct {
	next func() (void, bool)
	stop func()
}

type EventLoop struct {
	coros []coro
}

func NewEventLoop() *EventLoop {
	return &EventLoop{}
}

func (e *EventLoop) AddTask(task func(func(void) bool)) {
	next, stop := iter.Pull(task)
	e.coros = append(e.coros, coro{
		next: next,
		stop: stop,
	})
}

func (e *EventLoop) Run() {
	for len(e.coros) > 0 {
		// random pick a event
		i := rand.Intn(len(e.coros))

		// run coroutine
		_, ok := e.coros[i].next()

		// if finish, then remove it from evloop
		if !ok {
			e.coros = append(e.coros[:i], e.coros[i+1:]...)
		}
	}
}

func get1(yield func(void) bool) {
	fmt.Println("1")
	yield(void{})
	fmt.Println("2")
	yield(void{})
	fmt.Println("3")
	yield(void{})
}

func get2(yield func(void) bool) {
	fmt.Println("4")
	yield(void{})
	fmt.Println("5")
	yield(void{})
	fmt.Println("6")
	yield(void{})
}

func main() {
	evLoop := NewEventLoop()
	evLoop.AddTask(get1)
	evLoop.AddTask(get2)

	evLoop.Run()
}

Changelog

Just observe 👀